#ifndef PICCOLO_RENDER_TARGET_H
#define PICCOLO_RENDER_TARGET_H

#include "ECS/PEntity.h"

#include "Graphics/PiccoloVKFrameBuffer.h"
#include "Render/PiccoloRenderContext.h"
#include "ECS/System/PMaterialSystem.h"

namespace Piccolo
{
    class PiccoloRenderTarget
    {
    public:
        PiccoloRenderTarget(PiccoloVKRenderPass* renderPass);
        PiccoloRenderTarget(PiccoloVKRenderPass* renderPass, uint32_t bufferCount, VkExtent2D extent);
        ~PiccoloRenderTarget();

        void Begin(VkCommandBuffer cmdBuffer);
        void End(VkCommandBuffer cmdBuffer);

        PiccoloVKRenderPass* GetRenderPass() const { return mRenderPass; }
        PiccoloVKFrameBuffer* GetCurrentFrameBuffer() const { return mFrameBuffers[mCurrentBufferIndex].get(); }

        void SetExtent(const VkExtent2D& extent);
        void SetBufferCount(uint32_t bufferCount);

        void SetColorClearValue(VkClearColorValue colorClearValue);
        void SetColorClearValue(uint32_t attachmentIndex, VkClearColorValue colorClearValue);
        void SetDepthStencilClearValue(VkClearDepthStencilValue depthStencilValue);
        void SetDepthStencilClearValue(uint32_t attachmentIndex, VkClearDepthStencilValue depthStencilValue);

        template<typename T, typename... Args>
        void AddMaterialSystem(Args&&... args)
        {
            std::shared_ptr<PMaterialSystem> system = std::make_shared<T>(std::forward<Args>(args)...);
            system->OnInit(mRenderPass);
            mMaterialSystemList.push_back(system);
        }

        void RenderMaterialSystemList(VkCommandBuffer cmdBuffer)
        {
            for (auto& item : mMaterialSystemList)
            {
                item->OnRender(cmdBuffer, this);
            }
        }

        void SetCamera(PEntity* camera) { mCamera = camera; }
        PEntity* GetCamera() const { return mCamera; }

    private:
        void Init();
        void Recreate();

        std::vector<std::shared_ptr<PiccoloVKFrameBuffer>> mFrameBuffers;
        std::vector<std::shared_ptr<PMaterialSystem>> mMaterialSystemList;
        PEntity* mCamera;

        PiccoloVKRenderPass* mRenderPass;
        std::vector<VkClearValue> mClearValues;
        uint32_t mBufferCount;
        uint32_t mCurrentBufferIndex = 0;
        VkExtent2D mExtent;

        // 是交换链的还是离屏渲染的
        bool bSwapchainTarget = false;
        bool bBeginTarget = false;
        bool bShouldUpdate = false;
    };
}

#endif